/* 线程池 */
#ifndef __THREAD_POOL_H__
#define __THREAD_POOL_H__

#include <pthread.h>

/* 任务队列 */
struct Task_t
{
    /* 回调函数 */
    void * (*function)(void * arg);     //任务的执行函数
    /* 回调函数的参数 */
    void * arg;
};

void * workerThreadFunc(void * arg);
void * managerThreadFunc(void * arg);

class ThreadPool
{
public:
    /* 构造函数：创建线程池并初始化 */
    // 返回线程池指针，通过地址传递给其他函数才能使用该线程池的内容
    ThreadPool(int minThread, int maxThread, int maxQueueCapacity);
    /* 析构函数：销毁线程池 */
    ~ThreadPool();
public:
    /* 添加任务 */
    void addTask(void * (*function)(void * arg), void * arg);

public:
    /* 友元：可以访问类的私有和保护成员。友元函数声明在类的内部，但其实现可以在类外部 */
    friend void * workerThreadFunc(void * arg);
    friend void * managerThreadFunc(void * arg);

private:
    void exitThread( pthread_t tid);

    /* 任务队列 */
    Task_t * m_queue;   //队列先进先出
    /* 队列容量 */
    int m_queueCapacity;
    /* 队列的当前任务个数 */
    int m_queueSize;
    /* 队头 */
    int m_queueFront;   //取出数据
    /* 队尾 */
    int m_queueTail;    //放入数据

    /* 工作线程ID */
    pthread_t * m_threadId;     //保存线程池中线程的id，工作线程有多个，是一个数组，所以定义为指针，由指针指向工作线程数组，要动态分配
    /* 管理者线程ID */
    pthread_t m_managerThreadId;    //管理者线程一个就可以了，所以用pthread_t就可以

    /* 存活的线程数 */
    int m_aliveThreadNum;
    /* 忙碌的线程数 */
    int m_busyThreadNum;
    /* 最小的线程数（下限） */
    int m_minThreadNum;
    /* 最大的线程数（上限） */
    int m_maxThreadNum;
    /* 要减少的线程数 */
    int exitNum;

    /* 锁整个线程池 */
    pthread_mutex_t m_mutex;        //保证线程同步，防止不同线程取数据时产生混乱
    /* 忙碌锁：锁住busyNum，因为busyNum的变化频率高，锁住可以提高效率 */
    pthread_mutex_t m_busyMutex;

    /* 条件变量 */
    pthread_cond_t m_queueNotEmpty;     //任务队列不为空的条件
    /* 条件变量 */
    pthread_cond_t m_queueNotFull;      //任务队列不为满的条件

    

};




#endif